package com.cq.hd.product.factory;

import com.alibaba.fastjson.JSON;
import com.cq.hd.common.constant.Constant;
import com.cq.hd.common.enums.biz.*;
import com.cq.hd.common.response.Throw;
import com.cq.hd.common.utils.BeanUtils;
import com.cq.hd.common.utils.GenerateUtil;
import com.cq.hd.common.utils.LocalDateUtil;
import com.cq.hd.common.utils.NoUtils;
import com.cq.hd.member.api.TbBusinessApi;
import com.cq.hd.member.api.dto.UpdateActiveCountDto;
import com.cq.hd.member.api.vo.BusinessVo;
import com.cq.hd.product.api.dto.ActiveContent;
import com.cq.hd.product.api.dto.ActiveReleaseDto;
import com.cq.hd.product.mapper.TbActiveMapper;
import com.cq.hd.product.po.TbActivePo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Component
@Slf4j
public class ExternalActiveReleaseHandler extends AbstractActiveReleaseHandler {

    @Autowired
    private TbActiveMapper activeMapper;

    @Autowired
    private TbBusinessApi businessApi;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Value("${spring.profiles.active}")
    private String env;

    @Override
    protected Integer getType() {
        return ActiveTypeEnum.EXTERNAL.getValue();
    }

    @Override
    public Long saveActiveData(ActiveReleaseDto activeReleaseDto) {
        // 活动类型(1-团购活动，2-报名活动，3-外部活动)
        String activeTitle = activeReleaseDto.getActiveTitle();
        String activeImg = activeReleaseDto.getActiveImg();
        List<ActiveContent> activeContents = activeReleaseDto.getActiveContents();
        BigDecimal activePrice = activeReleaseDto.getActivePrice();
        BigDecimal originPrice = activeReleaseDto.getOriginPrice();
        // 活动状态（1-仅保存，2-去发布）
        Integer activeState = activeReleaseDto.getActiveState();
        // 是否是零元购活动（1-不是，2-是）
        Integer zeroState = activeReleaseDto.getZeroState();

        if (zeroState == null || ZeroStateEnum.typeOf(zeroState) == null) {
            Throw.isBusinessException("请选择零元购状态");
        }

        if (activeState == null || (activeState != 1 && activeState != 2)) {
            Throw.isBusinessException("活动状态值错误");
        }

        if (StringUtils.isEmpty(activeTitle)) {
            Throw.isBusinessException("请输入活动标题");
        }

        if (StringUtils.isEmpty(activeImg)) {
            Throw.isBusinessException("请上传活动图片");
        }

        if (CollectionUtils.isEmpty(activeContents)) {
            Throw.isBusinessException("请输入活动内容");
        } else {
            for (ActiveContent activeContent : activeContents) {
                String content = activeContent.getContent();
                if (StringUtils.isEmpty(content)) {
                    Throw.isBusinessException("请输入活动内容");
                }
            }
        }

        if(ZeroStateEnum.NO.getValue().equals(zeroState)){
            // 如果是测试环境，活动价格不能少于0.1元，否则不能少于1元
            if ("test".equals(env)) {
                if (activePrice == null || activePrice.compareTo(new BigDecimal("0.1")) < 0) {
                    Throw.isBusinessException("活动价格不能少于0.1元");
                }
            } else {
                if (activePrice == null || activePrice.compareTo(new BigDecimal("1")) < 0) {
                    Throw.isBusinessException("活动价格不能少于1元");
                }
            }
        }
        else{
            activePrice = BigDecimal.ZERO;
        }

        if (originPrice != null && originPrice.compareTo(BigDecimal.ZERO) > 0) {
            if (originPrice.compareTo(new BigDecimal("99999999")) > 0) {
                Throw.isBusinessException("划线价格必须小于99999999元");
            }

            if (originPrice.compareTo(activePrice) < 0) {
                Throw.isBusinessException("划线价格必须大于等于活动价格");
            }
        }

        // 校验活动时间
        String startTime = activeReleaseDto.getStartTime();
        String endTime = activeReleaseDto.getEndTime();

        if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
            Throw.isBusinessException("请设置活动时间");
        }

        LocalDateTime startLocalDateTime = null;
        LocalDateTime endLocalDateTime = null;
        try {
            startLocalDateTime = LocalDateUtil.toLocalDateTime(startTime, Constant.YYYY_MM_DD_HH_MM_SS);
            endLocalDateTime = LocalDateUtil.toLocalDateTime(endTime, Constant.YYYY_MM_DD_HH_MM_SS);
        } catch (Exception e) {
            Throw.isBusinessException("活动时间设置有误");
        }

        LocalDateTime nowLocalDateTime = LocalDateUtil.getNowLocalDateTime();

        // 活动开始时间，不能早于当前时间
        if (nowLocalDateTime.compareTo(startLocalDateTime) >= 0) {
            Throw.isBusinessException("活动开始时间不能早于当前时间");
        }

        // 活动开始时间，不能大于活动结束时间
        if (startLocalDateTime.compareTo(endLocalDateTime) >= 0) {
            Throw.isBusinessException("活动开始时间不能晚于活动结束时间");
        }

        // 活动链接不能为空
        String activeUrl = activeReleaseDto.getActiveUrl();
        if (StringUtils.isEmpty(activeUrl)) {
            Throw.isBusinessException("请填写活动链接");
        }

        if (ActiveStateEnum.NO_START.getValue().equals(activeState)) {
            // 判断商家发布活动次数是否足够
            BusinessVo businessVo = businessApi.getActiveCount(activeReleaseDto.getUserId(), activeReleaseDto.getBusinessId()).unpack();
            if (businessVo != null) {
                Integer activeCount = businessVo.getActiveCount();
                if (activeCount < 1) {
                    Throw.isBusinessException("发布活动次数不足");
                }
            }
        }

        // 添加活动数据
        TbActivePo tbActivePo = new TbActivePo();
        BeanUtils.copyProperties(activeReleaseDto, tbActivePo);
        tbActivePo.setContent(JSON.toJSONString(activeContents));
        // 活动状态（1-仅保存，2-去发布）
        tbActivePo.setActiveState(ActiveStateEnum.NO_RELEASE.getValue().equals(activeState)
                ? ActiveStateEnum.NO_RELEASE.getValue()
                : ActiveStateEnum.NO_START.getValue());
        tbActivePo.setActiveNo(NoUtils.getActiveNo());
        tbActivePo.setRemainStock(activeReleaseDto.getTotalStock());
        tbActivePo.setStartTime(startLocalDateTime);
        tbActivePo.setEndTime(endLocalDateTime);
        tbActivePo.setCreateTime(nowLocalDateTime);
        if (ActiveStateEnum.NO_START.getValue().equals(tbActivePo.getActiveState())) {
            tbActivePo.setReleaseTime(nowLocalDateTime);
        }

        int count;

        TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

        try {
            if (tbActivePo.getId() == null) {
                count = activeMapper.insert(tbActivePo);
            } else {
                count = activeMapper.updateById(tbActivePo);
            }
            if (count == 0) {
                log.error("添加活动失败，保存活动数据异常");
                Throw.isBusinessException("添加活动失败");
            }
            Long activeId = tbActivePo.getId();

            // 如果是发布活动，则扣除商家活动次数，并记录活动次数流水
            if (ActiveStateEnum.NO_START.getValue().equals(activeState)) {
                UpdateActiveCountDto updateActiveCountDto = new UpdateActiveCountDto();
                updateActiveCountDto.setBusinessId(activeReleaseDto.getBusinessId());
                updateActiveCountDto.setUserId(activeReleaseDto.getUserId());
                updateActiveCountDto.setRelationId(activeId);
                updateActiveCountDto.setTradeActiveCount(1);
                updateActiveCountDto.setTradeType(ActiveCountTradeTypeEnum.RELEASE_ACTIVE.getValue());
                updateActiveCountDto.setTradeTime(nowLocalDateTime);
                Boolean updateState = businessApi.subActiveCount(updateActiveCountDto).unpack();
                if (!updateState) {
                    log.error("添加活动失败，扣除发布活动个数异常");
                    Throw.isBusinessException("发布活动次数不足");
                }
            }

            transactionManager.commit(transaction);
        } catch (Exception e) {
            //回滚事务
            transactionManager.rollback(transaction);
            log.error("<添加外部活动>事务异常回滚", e);
            Throw.isBusinessException(e.getMessage());
        }

        return tbActivePo.getId();
    }

}
